package foo.bar.wiki.services;

import org.springframework.orm.jpa.JpaTemplate;
import org.springframework.orm.jpa.JpaCallback;
import com.sun.syndication.feed.synd.*;
import foo.bar.wiki.domain.Page;
import foo.bar.wiki.domain.Space;
import foo.bar.wiki.domain.Comment;
import foo.bar.wiki.web.action.space.SpaceActionBean;
import foo.bar.wiki.web.action.page.PageActionBean;
import foo.bar.wiki.radeox.DefaultWikiRenderEngine;
import foo.bar.radeox.api.engine.RenderEngine;
import foo.bar.radeox.api.engine.context.RenderContext;
import foo.bar.radeox.engine.context.BaseRenderContext;

import java.util.*;

import net.sourceforge.stripes.util.UrlBuilder;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceException;
import javax.persistence.Query;

/**
 * @author tmjee
 * @version $Date$ $Id$
 */
public class FeedsService extends AbstractFeedsService {

    private WikiService wikiService;

    private RenderEngine renderEngine;

    FeedsService(){}
    public FeedsService(JpaTemplate template, RenderEngine renderEngine, WikiService wikiService) {
        super(template);
        this.renderEngine = renderEngine;
        this.wikiService = wikiService;
    }


    public SyndFeed produceSpaceFeeds(final Space space, FeedType feedType) {

            List<Page> pages =  (List<Page>) getJpaTemplate().execute(new JpaCallback() {
                public Object doInJpa(EntityManager entityManager) throws PersistenceException {
                    Query q1 = entityManager.createNamedQuery("Page_findLatestPagesBySpaceId");
                    q1.setParameter("spaceId", space.getId());
                    return q1.getResultList();
                }
            });


            SyndFeed feed = new SyndFeedImpl();
            feed.setDescription("Latest Space Details");
            feed.setCopyright("Copyright FooBarWiki. Released Under Apache 2 License");
            feed.setEncoding("UTF-8");
            feed.setFeedType(feedType.toString());
            feed.setLanguage(Locale.getDefault().getLanguage());
            feed.setTitle("Latest Space Details");

            String spaceUrl = buildSpaceUrl(space);
            feed.setLink(spaceUrl);
            feed.setUri(spaceUrl);

            SyndLink selfLink = new SyndLinkImpl();
            selfLink.setHref(feed.getUri());
            selfLink.setRel("self");
            feed.setLinks(Collections.singletonList(selfLink));

            // publishedDate
            if (pages != null && pages.size() > 0) {
                Page latestPage = (Page) pages.iterator().next();
                if (latestPage.getModificationDate() != null) {
                    feed.setPublishedDate(latestPage.getModificationDate());
                }
                else {
                    feed.setPublishedDate(latestPage.getCreationDate());
                }
            }
            List<SyndEntry> _entries = new ArrayList<SyndEntry>();
            for (Page page : pages) {
                SyndEntry syndPage = new SyndEntryImpl();
                syndPage.setAuthor(page.getCreator().getUsername());

                List<SyndContent> contents = new ArrayList<SyndContent>();
                SyndContent syndContent = new SyndContentImpl();
                syndContent.setMode("text");
                syndContent.setType("text/plain");
                RenderContext renderContext = new BaseRenderContext();
                renderContext.getParameters().put(DefaultWikiRenderEngine.RENDER_CONTEXT_SPACE_ID_PARAM_KEY, page.getSpace().getId());
                syndContent.setValue(renderEngine.render(page.getContent(), renderContext));
                contents.add(syndContent);
                syndPage.setContents(contents);

                List<SyndPerson> _contributors = new ArrayList<SyndPerson>();
                SyndPerson _syndPerson = new SyndPersonImpl();
                _syndPerson.setEmail(page.getCreator().getEmail());
                _syndPerson.setName(page.getCreator().getUsername());
                _contributors.add(_syndPerson);
                syndPage.setContributors(_contributors);

                SyndContent _syndContent = new SyndContentImpl();
                _syndContent.setMode("text");
                _syndContent.setType("text/plain");
                _syndContent.setValue(page.getDescription());
                syndPage.setDescription(_syndContent);


                String pageUrl = buildPageUrl(page);
                syndPage.setLink(pageUrl);

                SyndLink _syndLink = new SyndLinkImpl();
                _syndLink.setHref(syndPage.getLink());
                _syndLink.setRel("self");
                syndPage.setLinks(Collections.singletonList(_syndLink));

                syndPage.setPublishedDate(page.getCreationDate());
                syndPage.setTitle(page.getName());
                syndPage.setUri(syndPage.getLink());
                syndPage.setUpdatedDate(page.getModificationDate());

                _entries.add(syndPage);
            }
            feed.setEntries(_entries);
            return feed;
    }

    public SyndFeed producePageFeeds(Page page, FeedType feedType) {
        SyndFeed feed = new SyndFeedImpl();
        feed.setDescription("Latest Page Details");
        feed.setCopyright("Copyright FooBarWiki. Released Under Apache 2 License");
        feed.setEncoding("UTF-8");
        feed.setFeedType(feedType.toString());
        feed.setLanguage(Locale.getDefault().getLanguage());
        feed.setTitle("Latest Page Details");

        String pageUrl = buildPageUrl(page);
        feed.setLink(pageUrl);
        feed.setUri(pageUrl);

        SyndLink selfLink = new SyndLinkImpl();
        selfLink.setHref(feed.getUri());
        selfLink.setRel("self");
        feed.setLinks(Collections.singletonList(selfLink));

        List<SyndEntry> syndComments = new ArrayList<SyndEntry>();
        for (Comment comment : page.getComments()) {
            SyndEntry syndComment = new SyndEntryImpl();

            syndComment.setAuthor(comment.getCreator().getUsername());

            List<SyndContent> contents = new ArrayList<SyndContent>();
            SyndContent syndContent = new SyndContentImpl();
            syndContent.setMode("text");
            syndContent.setType("text/plain");
            RenderContext renderContext = new BaseRenderContext();
            renderContext.getParameters().put(DefaultWikiRenderEngine.RENDER_CONTEXT_SPACE_ID_PARAM_KEY, page.getSpace().getId());
            syndContent.setValue(renderEngine.render(comment.getContent(), renderContext));
            contents.add(syndContent);
            syndComment.setContents(contents);

            List<SyndPerson> _contributors = new ArrayList<SyndPerson>();
            SyndPerson _syndPerson = new SyndPersonImpl();
            _syndPerson.setEmail(comment.getCreator().getEmail());
            _syndPerson.setName(comment.getCreator().getUsername());
            _contributors.add(_syndPerson);
            syndComment.setContributors(_contributors);

            String _pageUrl = buildPageUrl(page);
            syndComment.setLink(_pageUrl);

            SyndLink _syndLink = new SyndLinkImpl();
            _syndLink.setHref(syndComment.getLink());
            _syndLink.setRel("self");
            syndComment.setLinks(Collections.singletonList(_syndLink));

            syndComment.setPublishedDate(page.getCreationDate());
            syndComment.setTitle(page.getName());
            syndComment.setUri(syndComment.getLink());
            syndComment.setUpdatedDate(page.getModificationDate());

            syndComments.add(syndComment);
        }
        feed.setEntries(syndComments);
        return feed;
    }


    protected String buildSpaceUrl(Space space) {
        UrlBuilder urlBuilder = new UrlBuilder(Locale.getDefault(), SpaceActionBean.class, false);
        urlBuilder.addParameter("space", space.getId());
        return buildUrlPrefix()+urlBuilder.toString();
    }

    protected String buildPageUrl(Page page) {
        UrlBuilder urlBuilder = new UrlBuilder(Locale.getDefault(), PageActionBean.class, false);
        urlBuilder.addParameter("page", page.getId());
        return buildUrlPrefix() + urlBuilder.toString();
    }


    
}
